/*
 * Copyright 2005 Lumis EIP Tecnologia da Informação
 */

package lumis.doui.control.form;

import lumis.doui.control.Control;
import lumis.doui.control.ControlContainer;
import lumis.doui.control.IControl;
import lumis.doui.control.IFormControl;
import lumis.doui.processaction.ProcessActionHandler;
import lumis.portal.*;
import lumis.portal.serviceinterface.IServiceInterfaceUrl;
import lumis.util.XmlUtil;
import java.net.URLEncoder;

import java.util.Map;

import org.w3c.dom.*;

/**
 * Defines a form control. Use this control when you want to render a form that posts user input to the server.
 * 
 * <br/>
 * <br/> 
 * Example use:
 * <xmp>
 * <control:lum_form>
 * 	<!-- controls within the form -->
 * </control:lum_form>
 * </xmp>
 * 
 * xml data available for xsl rendering:
 * <xmp>
 *<control id="FF80808110EC81EF0110EEBF13D600BB" type="lum_form">
 * 	<!-- controls within the form -->
 *	<data>
 *		<name>Form_4028802410E199490110E1F2C84300FA</name> 
 *		<method>POST</method> 
 *		<action>main.jsp?lumPageId=1D6530765D5644709741AEAA3622D3BC&amp;lumII=4028802410E199490110E1F2C84300FA</action> 
 *	</data>
 *</control>
 * </xmp>
 * 
 * 
 * @version $Revision: 11039 $ $Date: 2009-10-29 16:07:52 -0200 (Thu, 29 Oct 2009) $
 * @since 4.0.6
 */
public class FormControl extends Control implements IFormControl
{
	private String encodingType;
	private boolean hasRequiredFields = false;
	
	@Override
	public void init(Node controlDefinitionNode, ControlContainer controlContainer, IControl parentControl) throws PortalException
	{
		super.init(controlDefinitionNode, controlContainer, parentControl);

		String formName = XmlUtil.readAttributeString("formName", controlDefinitionNode, "Form_" + douiContext.getRequest().getServiceInterfaceInstanceId());
		controlContainer.setFormName(formName);
	}

	public void setRenderData() throws PortalException
	{
		try
		{
			super.setRenderData();

			douiContext.getRenderResponse().getBeforeWriter().print("<script type=\"text/javascript\" charset=\"UTF-8\" src=\"lumis/doui/client/script/LumisDoui.js\"></script><noscript><!--Lumis portal script--></noscript>", "LumisDoui.js");
			
			String defaultOnEnterProcessActionId = null;
			String onEnterProcessActionId = XmlUtil.readAttributeString("onEnterProcessActionId", controlDefinitionNode, defaultOnEnterProcessActionId);
			
			boolean onEnterRenderAction = XmlUtil.readAttributeBoolean("onEnterRenderAction", controlDefinitionNode, false);

			String formName = XmlUtil.readAttributeString("formName", controlDefinitionNode, "Form_" + douiContext.getRenderRequest().getServiceInterfaceInstanceId());
			String formMethod = XmlUtil.readAttributeString("formMethod", controlDefinitionNode, "post");
			String formAction = XmlUtil.readAttributeString("formAction", controlDefinitionNode);
			if (formAction == null)
			{
				IServiceInterfaceUrl url = douiContext.getRenderResponse().createActionURL();
				formAction = url.toString();
			}
			
			controlContainer.setFormName(formName);

			Node dataNode = XmlUtil.addNode(controlDefinitionNode, "data");
			XmlUtil.addTextNode(dataNode, "name", formName);
			XmlUtil.addTextNode(dataNode, "method", formMethod);
			XmlUtil.addTextNode(dataNode, "action", formAction);
			
			if(onEnterProcessActionId != null)
			{
				StringBuilder onClickXml = new StringBuilder();
				onClickXml.append(XmlUtil.XML_HEADER+"<onClick type=\"processAction\">");
				onClickXml.append("<processActionId>"+onEnterProcessActionId+"</processActionId>");		
				onClickXml.append("</onClick>");

				XmlUtil.addNodeFromXmlString(controlDefinitionNode, onClickXml.toString());
				
				String onClick = getClientEventHandlerScript("onClick", false);

				if (onClick != null)
					XmlUtil.addTextNode(dataNode, "onEnterScript", onClick+";return false;");
			}
			else if(onEnterRenderAction)
			{
				String onEnterRenderActionId = XmlUtil.readAttributeString("onEnterRenderActionId", controlDefinitionNode, defaultOnEnterProcessActionId);
				
				StringBuilder onClickXml = new StringBuilder();
				onClickXml.append(XmlUtil.XML_HEADER+"<onClick type=\"renderAction\">");
				if(onEnterRenderActionId != null)
					onClickXml.append("<renderActionId>"+onEnterProcessActionId+"</renderActionId>");		
				onClickXml.append("</onClick>");

				XmlUtil.addNodeFromXmlString(controlDefinitionNode, onClickXml.toString());
				
				String onClick = getClientEventHandlerScript("onClick", false);

				if (onClick != null)
					XmlUtil.addTextNode(dataNode, "onEnterScript", onClick+";return false;");
			}

				
			if(encodingType != null && encodingType.length()>0)
				XmlUtil.addTextNode(dataNode, "encodingType", encodingType);

			// save the stored values in the form
			setStoredContextValues(dataNode);

			// handle form scripts
			StringBuilder scriptString = new StringBuilder();

			if (douiContext.getRenderRequest().getParameter(ProcessActionHandler.RESPONSE_TYPE_RUN_JAVASCRIPT) != null)
			{
				scriptString.append(douiContext.getRenderRequest().getParameter(ProcessActionHandler.RESPONSE_TYPE_RUN_JAVASCRIPT));
			}

			if (douiContext.getRenderRequest().getParameter(ProcessActionHandler.RESPONSE_TYPE_REFRESH_PARENT) != null)
			{
				scriptString.append("try{window.opener.LumisPortal.onRefresh();}catch(err){}");
			}

			if (douiContext.getRenderRequest().getParameter(ProcessActionHandler.RESPONSE_TYPE_CLOSE_WINDOW) != null)
			{
				scriptString.append("window.close();");
			}

			if (scriptString.length() > 0)
				XmlUtil.addTextNode(dataNode, "script", scriptString.toString());
		}
		catch (PortalException e)
		{
			throw e;
		}
		catch (Exception e)
		{
			throw new UnexpectedException(e);
		}
	}

	protected void setStoredContextValues(Node dataNode) throws PortalException
	{
		try
		{
			StringBuilder storedValues = new StringBuilder();

			for (Map.Entry entry : douiContext.getStoredValues().entrySet())
			{
				String storedKey = URLEncoder.encode(entry.getKey().toString(), "UTF-8");
				String storedValue = URLEncoder.encode(entry.getValue().toString(), "UTF-8");

				if (storedValue.length() > 0)
				{
					if (storedValues.length() > 0)
						storedValues.append(";");

					storedValues.append(storedKey + "=" + storedValue);
				}
			}

			if (storedValues.length() > 0)
				XmlUtil.addTextNode(dataNode, "previousStoredValues", storedValues.toString());
		}
		catch (PortalException e)
		{
			throw e;
		}
		catch (Exception e)
		{
			throw new UnexpectedException(e);
		}
	}
	
	/**
	 * @return Returns the encodingType.
	 */
	public String getEncodingType()
	{
		return encodingType;
	}
	
	/**
	 * @param encodingType The encodingType to set.
	 */
	public void setEncodingType(String encodingType)
	{
		this.encodingType = encodingType;
	}

	/**
	 *
	 */

	public boolean hasRequiredFields() throws PortalException
	{
		return hasRequiredFields;
	}
	/**
	 *
	 */

	public void setHasRequiredFields(boolean requiredFields) throws PortalException
	{
		this.hasRequiredFields = requiredFields;
	}
}
